﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace PayloadTracker.APRS.SoundModem
{
    [SetupControlAttribute(typeof(SoundModemSetup))]
    public class SoundModem : IAPRSProvider
    {
        FSK m_FSK;
        AX25Deserializer m_Deserializer;
        int m_Device; 

        private SoundModem() 
            : base ("Soundcard Modem")
        {

        }
        public SoundModem(int device)
            : base("Soundcard Modem")
        {
            Initialize(device);
        }
        public static List<FSK.CaptureDevice> GetAvailableDevices()
        {
            return FSK.GetAvailableDevices();
        }
        private void Initialize(int device)
        {
            m_FSK = new FSK(FSK.Bell202, device);
            m_Deserializer = new AX25Deserializer();
            m_FSK.FSKBitReady += new FSKBitReadyDelegate(m_Deserializer.ProcessBit);
            m_Deserializer.AX25PacketReady += new AX25PacketReadyDelegate(m_Deserializer_AX25PacketReady);
            m_Device = device;

            foreach (var d in GetAvailableDevices())
                if (d.ID == device)
                    this.Name = "SoundModem: " + d.Name;
        }

        void m_Deserializer_AX25PacketReady(AX25Packet packet)
        {
            string ascii = System.Text.ASCIIEncoding.ASCII.GetString(packet.Data).Trim();
            string aprs_string = packet.CallsignTo.Trim()+"-"+packet.SSIDTo + ">APRS:@" + ((ascii.StartsWith("/") && ascii.Length > 1) ? ascii.Substring(1) : ascii);
            Logger.LOG.WriteLine("Received AX.25 Packet: (" + packet.CallsignFrom + "->" + packet.CallsignTo + "): " + ascii);

            Logger.LOG.Write("Trying to parse AX.25 packet for APRS Data... ("+aprs_string+")");
            
            APRSBeacon parsed = null;
            try
            {
                parsed = Parsers.ParserProvider.Instance.AutoParse(aprs_string);
            }
            catch (Exception)
            { }
            if (parsed == null)
                Logger.LOG.WriteLine("FAILED!");
            else 
            {
                Logger.LOG.WriteLine("Success!");
                OnAprsUpdate(parsed);
            }
        }

        public override void Start()
        {
            m_FSK.Start();
        }

        public override void Stop()
        {
            m_FSK.Stop();
        }

        public override void Tick()
        {
            //don't need to do anything here.
        }

        public override void ReadXml(System.Xml.XmlReader reader)
        {
            int DevID = -2;

            reader.MoveToNextAttribute();
            if (reader.Name.ToLower() == "device")
                DevID = Int32.Parse(reader.Value);

            reader.Read();
            if (DevID == -2)
                throw new System.Xml.XmlException("Missing attribute.");


            Initialize(DevID);
        }

        public override void WriteXml(System.Xml.XmlWriter writer)
        {
            writer.WriteAttributeString("Device", m_Device.ToString());
        }
    }
}
